package fun.hijklmn.magic.admin.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import fun.hijklmn.magic.admin.common.pojo.Role;
import fun.hijklmn.magic.admin.common.vo.req.RoleReqVO;
import fun.hijklmn.magic.admin.server.constants.RedisKeyConstant;
import fun.hijklmn.magic.admin.server.dao.RoleDao;
import fun.hijklmn.magic.admin.server.service.RoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import fun.hijklmn.magic.common.enums.StatusEnum;
import fun.hijklmn.magic.common.exception.MagicBizException;
import fun.hijklmn.magic.idGenerator.client.api.IdGeneratorServiceApi;
import fun.hijklmn.magic.idGenerator.common.enums.ServerTypeEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zsl
 * @since 2021-06-25
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleDao, Role> implements RoleService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IdGeneratorServiceApi idGeneratorServiceApi;

    @Override
    public Role save(RoleReqVO roleReqVO) {

        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.eq("is_delete", 0);

        StringBuilder stringBuilder = new StringBuilder();

        if (StringUtils.isNotEmpty(roleReqVO.getName())) {
            stringBuilder.append(String.format("name = '%s'", roleReqVO.getName()));
        }

        if (StringUtils.isNotEmpty(roleReqVO.getCode())) {
            if (stringBuilder.length() > 0) {
                stringBuilder.append(String.format(" or code = '%s'", roleReqVO.getName()));
            } else {
                stringBuilder.append(String.format("code = '%s'", roleReqVO.getName()));
            }
        }

        if (stringBuilder.length() > 0) {
            roleQueryWrapper.apply("(" + stringBuilder.toString() + ")");
        }

        List<Role> roleList = this.list(roleQueryWrapper);

        LocalDateTime curLocalDateTime = LocalDateTime.now();

        if (StringUtils.isNotEmpty(roleReqVO.getId())) {

            if (roleList.stream().filter(role -> roleReqVO.getId().equals(role.getId())).count() > 0) {
                throw new MagicBizException("角色名称或者角色简称已经存在");
            }

            Role updateRole = new Role();

            if (StringUtils.isNotEmpty(roleReqVO.getName())) {
                updateRole.setName(roleReqVO.getName());
            }

            if (StringUtils.isNotEmpty(roleReqVO.getCode())) {
                updateRole.setCode(roleReqVO.getCode());
            }

            if (StringUtils.isNotEmpty(roleReqVO.getIcon())) {
                updateRole.setIcon(roleReqVO.getIcon());
            }

            if (roleReqVO.getStatus() != null && StatusEnum.AdminRoleStatusEnum.containStatus(roleReqVO.getStatus())) {
                updateRole.setStatus(roleReqVO.getStatus());
            }

            updateRole.setUpdateTime(curLocalDateTime);

            this.update(updateRole, new UpdateWrapper<Role>().eq("id", roleReqVO.getId()));

            return updateRole;

        } else {

            if (roleList.size() > 0) {
                throw new MagicBizException("角色名称或者角色简称已经存在");
            }

            Role insertRole = new Role();

            BeanUtils.copyProperties(roleReqVO, insertRole);

            insertRole.setIsDelete(StatusEnum.RecordValidEnum.normal.isDelete());

            insertRole.setStatus(StatusEnum.AdminRoleStatusEnum.normal.status());

            insertRole.setCreateTime(curLocalDateTime);

            insertRole.setId(idGeneratorServiceApi.get(ServerTypeEnum.admin_server));

            this.save(insertRole);

            return insertRole;

        }

    }

    @Override
    public void delete(String roleId) {

        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.eq("is_delete", 0);
        roleQueryWrapper.eq("id", roleId);
        roleQueryWrapper.last("limit 1");

        Role role = this.getOne(roleQueryWrapper);

        if (role == null || role.getIsDelete()) {
            throw new MagicBizException("该角色已经被删除");
        }

        redisTemplate.delete(RedisKeyConstant.roleId_Permissions.concat(roleId));

        Role updateRole = new Role();
        updateRole.setIsDelete(StatusEnum.RecordValidEnum.deleted.isDelete());

        this.update(updateRole, new UpdateWrapper<Role>().eq("id", roleId));

    }

}
